import 'dart:convert';
import 'package:flutter/services.dart';
import '../models/word_book.dart';
import '../models/learning_progress.dart';
import '../models/word_card.dart';
import '../models/word_library.dart';
import 'storage_utils.dart';
import 'dart:io';

class WordBookService {
  static const String CURRENT_BOOK_KEY = 'current_book';
  static const String PROGRESS_PREFIX = 'progress_';
  static const String LIBRARY_PREFIX = 'library_';

  // 获取示例词书列表
  static Future<List<WordBook>> getSampleBooks() async {
    final String jsonString = await rootBundle.loadString('assets/data/sample_books.json');
    final List<dynamic> jsonList = json.decode(jsonString);
    List<WordBook> books = jsonList.map((json) => WordBook.fromJson(json)).toList();
    
    // 更新每本词书的实际单词数量
    List<WordBook> updatedBooks = [];
    for (WordBook book in books) {
      int actualTotalWords = await _getActualBookTotalWords(book.data);
      updatedBooks.add(
        WordBook(
          id: book.id,
          name: book.name,
          coverImage: book.coverImage,
          totalWords: actualTotalWords, // 使用实际数量
          description: book.description,
          category: book.category,
          data: book.data,
        )
      );
    }
    
    return updatedBooks;
  }

  // 获取当前选中的词书
  static Future<WordBook?> getCurrentBook() async {
    return await StorageUtils.get<WordBook>(
      CURRENT_BOOK_KEY,
      (json) => WordBook.fromJson(json),
    );
  }

  // 设置当前选中的词书
  static Future<void> setCurrentBook(WordBook book) async {
    // 更新词书的实际单词数量
    int actualTotalWords = await _getActualBookTotalWords(book.data);
    final updatedBook = WordBook(
      id: book.id,
      name: book.name,
      coverImage: book.coverImage,
      totalWords: actualTotalWords, // 使用实际数量
      description: book.description,
      category: book.category,
      data: book.data,
    );
    
    await StorageUtils.save(CURRENT_BOOK_KEY, updatedBook.toJson());
  }

  // 获取词书的学习进度
  static Future<LearningProgress> getBookProgress(String bookId, int totalWords) async {
    final progress = await StorageUtils.get<LearningProgress>(
      PROGRESS_PREFIX + bookId,
      (json) => LearningProgress.fromJson(json),
    );
    
    // 获取实际的单词总数
    int actualTotalWords = totalWords;
    if (totalWords <= 0) {
      WordBook? book = await getCurrentBook();
      if (book != null && book.id == bookId) {
        actualTotalWords = book.totalWords;
      } else {
        actualTotalWords = await getBookTotalWords(bookId);
      }
    }
    
    // 如果进度不存在，创建新进度，使用实际的单词总数
    if (progress == null) {
      return LearningProgress.empty(bookId, actualTotalWords);
    }
    
    // 如果存在但总单词数不一致，更新总单词数
    if (progress.totalWords != actualTotalWords) {
      return LearningProgress(
        bookId: progress.bookId,
        totalWords: actualTotalWords, // 使用实际数量
        learnedWords: progress.learnedWords,
        todayLearned: progress.todayLearned,
        dailyRecords: progress.dailyRecords,
      );
    }
    
    return progress;
  }

  // 保存词书的学习进度
  static Future<void> saveBookProgress(LearningProgress progress) async {
    await StorageUtils.save(PROGRESS_PREFIX + progress.bookId, progress.toJson());
  }

  // 更新今日学习的单词数量
  static Future<LearningProgress> updateTodayLearned(String bookId, int count) async {
    final WordBook? currentBook = await getCurrentBook();
    if (currentBook == null || currentBook.id != bookId) {
      throw Exception('当前词书不匹配');
    }

    final progress = await getBookProgress(bookId, currentBook.totalWords);
    final updatedProgress = progress.updateTodayLearned(count);
    await saveBookProgress(updatedProgress);
    return updatedProgress;
  }

  // 从词书中加载单词
  static Future<List<WordCard>> loadWordsFromBook(String bookId) async {
    // 首先检查是否已有词库
    final WordLibrary? library = await getWordLibrary(bookId);
    if (library != null) {
      // 如果已有词库，返回未学习的单词（不在新词词库和复习词库中的单词）
      final List<WordCard> allWords = await _loadAllWordsFromAssets(bookId);
      final Set<String> existingWords = {...library.newWords.map((w) => w.word), ...library.reviewWords.map((w) => w.word)};
      return allWords.where((word) => !existingWords.contains(word.word)).toList();
    }
    
    // 如果没有词库，返回所有单词
    return await _loadAllWordsFromAssets(bookId);
  }
  
  // 从资源文件加载所有单词
  static Future<List<WordCard>> _loadAllWordsFromAssets(String bookId) async {
    // 获取词书信息
    WordBook? book = await getCurrentBook();
    if (book == null || book.id != bookId) {
      // 如果当前词书不匹配，尝试从示例词书中查找
      final List<WordBook> sampleBooks = await getSampleBooks();
      final int index = sampleBooks.indexWhere((b) => b.id == bookId);
      if (index == -1) {
        throw Exception('找不到词书: $bookId');
      }
      book = sampleBooks[index];
    }
    
    // 使用词书的data字段作为路径前缀
    final String dataPath = book.data;
    
    final manifestContent = await rootBundle.loadString('AssetManifest.json');
    final Map<String, dynamic> manifestMap = json.decode(manifestContent);
    final List<String> assetPaths = manifestMap.keys
        .where((String key) => key.startsWith('$dataPath/'))
        .toList();

    final List<WordCard> words = [];

    for (final String assetPath in assetPaths) {
      try {
        final String jsonString = await rootBundle.loadString(assetPath);
        final Map<String, dynamic> jsonData = json.decode(jsonString);
        words.add(WordCard.fromJson(jsonData));
      } catch (e) {
        print('加载单词文件失败: $assetPath, 错误: $e');
        // 继续处理下一个文件
      }
    }

    return words;
  }
  
  // 获取词书的词库
  static Future<WordLibrary?> getWordLibrary(String bookId) async {
    return await StorageUtils.get<WordLibrary>(
      LIBRARY_PREFIX + bookId,
      (json) => WordLibrary.fromJson(json),
    );
  }
  
  // 保存词书的词库
  static Future<void> saveWordLibrary(WordLibrary library) async {
    await StorageUtils.save(LIBRARY_PREFIX + library.bookId, library.toJson());
  }
  
  // 初始化词库
  static Future<WordLibrary> initWordLibrary(String bookId) async {
    final WordLibrary library = WordLibrary.empty(bookId);
    await saveWordLibrary(library);
    return library;
  }
  
  // 将单词添加到新词词库
  static Future<WordLibrary> addWordToNew(String bookId, WordCard word) async {
    WordLibrary? library = await getWordLibrary(bookId);
    if (library == null) {
      library = await initWordLibrary(bookId);
    }
    
    final updatedLibrary = library.addToNew(word);
    await saveWordLibrary(updatedLibrary);
    return updatedLibrary;
  }
  
  // 将单词从新词词库移动到复习词库
  static Future<WordLibrary> moveWordToReview(String bookId, String word) async {
    WordLibrary? library = await getWordLibrary(bookId);
    if (library == null) {
      library = await initWordLibrary(bookId);
      return library;
    }
    
    final updatedLibrary = library.moveToReview(word);
    await saveWordLibrary(updatedLibrary);
    
    // 更新学习进度
    if (updatedLibrary != library) {
      final WordBook? currentBook = await getCurrentBook();
      if (currentBook != null && currentBook.id == bookId) {
        await updateTodayLearned(bookId, 1);
      }
    }
    
    return updatedLibrary;
  }
  
  // 将单词从复习词库移动到新词词库
  static Future<WordLibrary> moveWordToNew(String bookId, String word) async {
    WordLibrary? library = await getWordLibrary(bookId);
    if (library == null) {
      library = await initWordLibrary(bookId);
      return library;
    }
    
    final updatedLibrary = library.moveToNew(word);
    await saveWordLibrary(updatedLibrary);
    return updatedLibrary;
  }
  
  // 将单词添加到复习词库
  static Future<WordLibrary> addWordToReview(String bookId, WordCard word) async {
    WordLibrary? library = await getWordLibrary(bookId);
    if (library == null) {
      library = await initWordLibrary(bookId);
    }
    
    // 检查单词是否已存在于新词或复习词库中
    bool isInNewWords = library.newWords.any((w) => w.word == word.word);
    bool isInReviewWords = library.reviewWords.any((w) => w.word == word.word);
    
    WordLibrary updatedLibrary;
    
    if (isInNewWords) {
      // 如果在新词词库中，移动到复习词库
      updatedLibrary = library.moveToReview(word.word);
    } else if (!isInReviewWords) {
      // 如果不在复习词库中，直接添加
      final WordCard newWord = word.copyWith(status: 'review');
      final List<WordCard> updatedReviewWords = List.from(library.reviewWords)..add(newWord);
      updatedLibrary = WordLibrary(
        bookId: library.bookId,
        newWords: library.newWords,
        reviewWords: updatedReviewWords,
      );
    } else {
      // 已经在复习词库中，不需要更改
      return library;
    }
    
    await saveWordLibrary(updatedLibrary);
    
    // 更新今日学习进度
    if (!isInReviewWords) {
      await updateTodayLearned(bookId, 1);
    }
    
    return updatedLibrary;
  }
  
  // 更新单词的重复次数
  static Future<WordLibrary> updateWordRepeatCount(String bookId, String word, int count) async {
    WordLibrary? library = await getWordLibrary(bookId);
    if (library == null) {
      return await initWordLibrary(bookId);
    }
    
    final updatedLibrary = library.updateRepeatCount(word, count);
    await saveWordLibrary(updatedLibrary);
    return updatedLibrary;
  }
  
  // 获取速读模式的单词
  static Future<List<WordCard>> getSpeedReadingWords(String bookId) async {
    // 获取词库
    WordLibrary? library = await getWordLibrary(bookId);
    
    // 如果词库不存在，加载所有单词
    if (library == null) {
      return await _loadAllWordsFromAssets(bookId);
    }
    
    // 获取所有单词
    final List<WordCard> allWords = await _loadAllWordsFromAssets(bookId);
    
    // 过滤掉已经在新词词库和复习词库中的单词
    final Set<String> existingWords = {
      ...library.newWords.map((w) => w.word),
      ...library.reviewWords.map((w) => w.word)
    };
    
    return allWords.where((word) => !existingWords.contains(word.word)).toList();
  }
  
  // 获取跟读模式的单词
  static Future<List<WordCard>> getFollowReadingWords(String bookId) async {
    // 获取词库
    WordLibrary? library = await getWordLibrary(bookId);
    
    // 如果词库不存在，返回空列表
    if (library == null || library.newWords.isEmpty) {
      return [];
    }
    
    // 使用艾宾浩斯记忆曲线生成学习序列
    return library.generateReviewSequence();
  }
  
  // 获取挑战模式的单词
  static Future<List<WordCard>> getChallengeWords(String bookId) async {
    // 获取词库
    WordLibrary? library = await getWordLibrary(bookId);
    
    // 如果词库不存在或复习词库为空，返回空列表
    if (library == null || library.reviewWords.isEmpty) {
      return [];
    }
    
    // 随机打乱复习词库中的单词
    final List<WordCard> shuffledWords = List.from(library.reviewWords)..shuffle();
    return shuffledWords;
  }
  
  // 获取词书的实际单词总数
  static Future<int> getBookTotalWords(String bookId) async {
    try {
      // 获取词书信息
      WordBook? book = await getCurrentBook();
      if (book == null || book.id != bookId) {
        // 如果当前词书不匹配，尝试从示例词书中查找
        final List<WordBook> sampleBooks = await getSampleBooks();
        final int index = sampleBooks.indexWhere((b) => b.id == bookId);
        if (index == -1) {
          return 0;
        }
        book = sampleBooks[index];
      }
      
      return await _getActualBookTotalWords(book.data);
    } catch (e) {
      print('获取词书总单词数失败: $e');
      return 0;
    }
  }

  // 获取词书的实际单词总数（内部方法）
  static Future<int> _getActualBookTotalWords(String dataPath) async {
    try {
      final manifestContent = await rootBundle.loadString('AssetManifest.json');
      final Map<String, dynamic> manifestMap = json.decode(manifestContent);
      final List<String> assetPaths = manifestMap.keys
          .where((String key) => key.startsWith('$dataPath/'))
          .toList();
      
      return assetPaths.length;
    } catch (e) {
      print('获取词书实际单词数失败: $e');
      return 0;
    }
  }

  // 同步学习进度和词库数据
  static Future<void> syncProgressAndLibrary(String bookId) async {
    try {
      // 获取词库
      WordLibrary? library = await getWordLibrary(bookId);
      if (library == null) return;
      
      // 获取实际的总单词数
      final int actualTotalWords = await getBookTotalWords(bookId);
      
      // 计算已学习单词数（只计算复习词库的单词数量）
      final int learnedWords = library.reviewWords.length;
      
      // 获取当前进度
      final progress = await getBookProgress(bookId, actualTotalWords);
      
      // 如果与当前进度不一致，更新进度
      if (progress.totalWords != actualTotalWords || progress.learnedWords != learnedWords) {
        // 创建更新的进度对象
        final updatedProgress = LearningProgress(
          bookId: progress.bookId,
          totalWords: actualTotalWords,
          learnedWords: learnedWords,
          todayLearned: progress.todayLearned,
          dailyRecords: progress.dailyRecords,
        );
        
        // 保存更新的进度
        await saveBookProgress(updatedProgress);
      }
    } catch (e) {
      print('同步学习进度和词库数据失败: $e');
    }
  }
} 